package com.zx.mes.longsecurity.hyl.service.impl;

import com.zx.mes.hyl.common.pagemodel.LayPageHelper;
import com.zx.mes.hyl.common.pagemodel.SessionInfo;
import com.zx.mes.hyl.common.pagemodel.Tree;

import com.zx.mes.longsecurity.hyl.dao.ResourceRepository;
import com.zx.mes.longsecurity.hyl.dao.ResourceTypeRepository;
import com.zx.mes.longsecurity.hyl.dao.SysRepository;
import com.zx.mes.longsecurity.hyl.dao.UserRepository;
import com.zx.mes.longsecurity.hyl.domain.Tresource;
import com.zx.mes.longsecurity.hyl.domain.Trole;
import com.zx.mes.longsecurity.hyl.domain.Tuser;
import com.zx.mes.longsecurity.hyl.pagemodel.Resource;
import com.zx.mes.longsecurity.hyl.service.ResourceServiceI;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.*;

/**
 * @author hyl
 */
@Service
public class ResourceServiceImpl implements ResourceServiceI {

    @Autowired
    private ResourceRepository resourceRepository;

    @Autowired
    private ResourceTypeRepository resourceTypeRepository;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private SysRepository sysRepository;

    @Override
    public List<Tree> tree(SessionInfo sessionInfo) {
        List<Tree> listRutrn=new ArrayList<>();
        List<Tresource> tresourceList=resourceRepository.findAllJoinByUserId(sessionInfo.getId());
        listTreeReturn(listRutrn, tresourceList);
        return listRutrn;
    }

    private void listTreeReturn(List<Tree> listRutrn, List<Tresource> tresourceList) {
        for (int i=0;i<tresourceList.size();i++){
            Tree tree=new Tree();
            Tresource tresource=tresourceList.get(i);
            BeanUtils.copyProperties(tresource,tree);

            if (tresource.getTresource() != null) {
                tree.setPid(tresource.getTresource().getId());
            }
            tree.setText(tresource.getName());
            tree.setIconCls(tresource.getIcon());
            Map<String, Object> attr = new HashMap<String, Object>(10);
            attr.put("url", tresource.getUrl());
            tree.setAttributes(attr);
            listRutrn.add(tree);
        }
    }

    @Override
    public List<Tree> allTree(SessionInfo sessionInfo) {
        return tree(sessionInfo);
    }

    @Override
    public List<Tree> treeByTsys(SessionInfo sessionInfo) {
        return null;
    }

    @Override
    public List<Tresource> treeByTsysOrg(SessionInfo sessionInfo) {
        return null;
    }

    @Override
    public List<Resource> treeGrid(SessionInfo sessionInfo) {
        List<Resource> listReturn =new ArrayList<>();
        List<Tresource> tresourceList=resourceRepository.findAllJoinByUserId(sessionInfo.getId());

        for (int i=0;i<tresourceList.size();i++){
            Resource resource=new Resource();
            Tresource tresource=tresourceList.get(i);
            BeanUtils.copyProperties(tresource,resource);
            BeanUtils.copyProperties(tresource, resource);
            if (tresource.getTresource() != null) {
                resource.setPid(tresource.getTresource().getId());
                resource.setPname(tresource.getTresource().getName());
            }
            resource.setTypeId(tresource.getTresourcetype().getId());
            resource.setTypeName(tresource.getTresourcetype().getName());
            if (tresource.getIcon() != null && !"".equalsIgnoreCase(tresource.getIcon())) {
                resource.setIconCls(tresource.getIcon());
            }
            listReturn.add(resource);
        }

        return listReturn;
    }

    @Override
    public void add(Resource resource, SessionInfo sessionInfo) {
        Tresource t = new Tresource();
        BeanUtils.copyProperties(resource, t);
        //如果父级不为空且不等于""
        if (resource.getPid() != null && !"".equalsIgnoreCase(resource.getPid())) {
            t.setTresource(resourceRepository.getOne(resource.getPid()));
        }
        //针对treegrid做的一步查询(tree不做)
        if (resource.getTypeId() != null && !"".equalsIgnoreCase(resource.getTypeId())) {
            t.setTresourcetype(resourceTypeRepository.findById(resource.getTypeId()));
        }
        //
        if (resource.getIconCls() != null && !"".equalsIgnoreCase(resource.getIconCls())) {
            t.setIcon(resource.getIconCls());
        }

        //Tsys tsys=new Tsys();
        //tsys=sysDao.get(Tsys.class,"10002");
        t.setTsys(sysRepository.getOne("10002"));

        resourceRepository.save(t);

        // 由于当前用户所属的角色，没有访问新添加的资源权限，所以在新添加资源的时候，将当前资源授权给当前用户的所有角色，以便添加资源后在资源列表中能够找到
        Tuser user = userRepository.getOne(sessionInfo.getId());
        Set<Trole> roles = user.getTroles();
        for (Trole r : roles) {
            r.getTresources().add(t);
        }
    }

    @Override
    public void delete(String id) {
        Tresource t=resourceRepository.getOne(id);
        del(t);
    }

    private void del(Tresource t) {
        if (t.getTresources() != null && t.getTresources().size() > 0) {
            for (Tresource r : t.getTresources()) {
                del(r);
            }
        }
        resourceRepository.delete(t);
    }

    @Override
    public void edit(Resource resource) {

        Tresource t=resourceRepository.getOne(resource.getId());
        if (t != null) {
            BeanUtils.copyProperties(resource, t);
            if (resource.getTypeId() != null && !"".equalsIgnoreCase(resource.getTypeId())) {
                // 赋值资源类型
                t.setTresourcetype(resourceTypeRepository.getOne(resource.getTypeId()));
            }
            if (resource.getIconCls() != null && !"".equalsIgnoreCase(resource.getIconCls())) {
                t.setIcon(resource.getIconCls());
            }
            // 说明前台选中了上级资源
            if (resource.getPid() != null && !"".equalsIgnoreCase(resource.getPid())) {
                Tresource pt = resourceRepository.getOne(resource.getPid());

                t.setTresource(pt);
            } else {
                // 前台没有选中上级资源，所以就置空
                t.setTresource(null);
            }
        }

    }

    @Override
    public Resource get(String id) {
        Tresource t=resourceRepository.getById(id);
        Resource r = new Resource();
        BeanUtils.copyProperties(t, r);
        if (t.getTresource() != null) {
            r.setPid(t.getTresource().getId());
            r.setPname(t.getTresource().getName());
        }
        r.setTypeId(t.getTresourcetype().getId());
        r.setTypeName(t.getTresourcetype().getName());
        if (t.getIcon() != null && !t.getIcon().equalsIgnoreCase("")) {
            r.setIconCls(t.getIcon());
        }
        return r;
    }

    @Override
    public List<Resource> findAll(Resource resource, LayPageHelper ph) {
        List<Resource> listReturn = new ArrayList<>();

        Pageable pageable=new PageRequest(ph.getPage()-1, ph.getLimit());
        List<Tresource> tresourceList =resourceRepository.findAll(getSpec(resource),pageable).getContent();

        for (int i=0;i<tresourceList.size();i++){
            Resource r=new Resource();
            Tresource tresource=tresourceList.get(i);

            BeanUtils.copyProperties(tresource, r);
            if (tresource.getTresource() != null) {
                r.setPid(tresource.getTresource().getId());
                r.setPname(tresource.getTresource().getName());
            }
            r.setTypeId(tresource.getTresourcetype().getId());
            r.setTypeName(tresource.getTresourcetype().getName());
            if (tresource.getIcon() != null && !"".equalsIgnoreCase(tresource.getIcon())) {
                r.setIconCls(tresource.getIcon());
            }
            listReturn.add(r);
        }
        return listReturn;
    }

    @Override
    public long count(Resource resource) {
        return resourceRepository.count(getSpec(resource));
    }


    private Specification<Tresource> getSpec(Resource resource) {
        return new Specification<Tresource>() {
            @Override
            public Predicate toPredicate(Root<Tresource> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> predicateList=new ArrayList<>();
                if (resource.getName()!=null && ! "".equalsIgnoreCase(resource.getName())){
                    predicateList.add(cb.like(root.get("name").as(String.class),"%"+resource.getName()+"%"));
                }

                query.where(predicateList.toArray(new Predicate[predicateList.size()]));
                return null;
            }
        };
    }
}
